import java.lang.reflect.Method;
import java.util.ArrayList;
import processing.core.*;

/**
 * 
 * Main Interface is responsible for displaying and handling the events for all of the
 * buttons, windows, and visual objects which the user interacts with.  Its local in the respect
 * that it belongs to the User / Application.  Interaction with it affects the User's Configuration.
 *
 */
public class mainInterface {
  protected PApplet parent;
  
  //displays the configuration window for handling ip/osc interfacing
  public Button[] configureButtons;
  private PImage welcomeBack, configureBack;
  private PImage joinSessionUp, joinSessionDown;
  private PImage newSessionUp, newSessionDown;
  private PImage joinUp, joinDown;
  private PImage startUp, startDown;
  private PImage longEntryBox, entryBox;
  private PImage longButton_up, longButton_down, button_up, button_down;
  private PImage bucket, vertEdge;
  protected String ipEntry, aliasEntry, selectedTextBox;
  
  protected int sessionConfigurationView;
  protected static final int HIDDEN = -1, SELECTALIAS = 0, WELCOME = 1, DISPLAYIP = 2, ENTERIP = 3;
  
  protected int menuView;
  protected static final int DRAWING = 0, TEXT = 1, ACTIONS = 2;
  
  //buttons control
  protected static final int UP = 0, OVER = 1, DOWN = 2;
  
  //displays the menu which in turns affects each user's configuration
  public Button[] menuElements;
  private PImage menu;
  private PImage drawmodeUp, drawmodeDown;
  private PImage textmodeUp, textmodeDown;
  private PImage actionsmodeUp, actionsmodeDown;
  private PImage outputUp, outputDown;
  private Configuration config;
  private int menuY;

  
  public mainInterface(PApplet _p){
    parent = _p;
    
    loadImages();
      
    sessionConfigurationView = WELCOME; //used to manage the flow of the configuration process
    ipEntry = "";
    
    menuView = HIDDEN;
    
    parent.fill(0);
  }
  
  
  public void exist() {
    
    if (sessionConfigurationView != HIDDEN) {
      
      //draw configuration background
      parent.image(welcomeBack, parent.width / 2 -  welcomeBack.width / 2, parent.height / 3 - welcomeBack.height / 2);
      
      if (sessionConfigurationView == SELECTALIAS) {
        enterAlias();
      } else if ( sessionConfigurationView == WELCOME) {
        newSessionView();
      } else if ( sessionConfigurationView == DISPLAYIP) {
        displayIPView();
      } else if ( sessionConfigurationView == ENTERIP) {
        enterIPView();
      }
      
    }
    
    
    
    if (menuView != HIDDEN) {
      
      //draw menubar
      for(int i = 0; i < parent.width; i = i + menu.width) {
        parent.image(menu, i, parent.height - menu.height);
      }
      
      if (config == null) {
        parent.println("Inside of gui exist, config is currently null.");
      } else {
        menuView = config.getMode();
      }
      
      for(int i = 0; i < menuElements.length; i++) {
        menuElements[i].draw();
      }
  
    }
    
  }
  
  public int getMenuY() {
    return menuY;
  }
  
  
  
  
  /** Calling these draws the existing "views" **/
  
  public void enterAlias() {
    configureButtons[4].setDisplay(UP);
    parent.text("Please Enter an Alias",parent.width/2 - 150,parent.height/3);
    int left = parent.width/2 - longEntryBox.width/2;
    int top = parent.height/3+18;
    parent.image(longEntryBox,left,top);
    parent.text(aliasEntry, left+2,top+6,longEntryBox.width-2,longEntryBox.height);
    configureButtons[4].draw();
  }
  
  public void newSessionView() {
    configureButtons[0].draw();
    configureButtons[1].draw();
  }
  
  public void displayIPView() {
    configureButtons[3].setDisplay(UP);
    parent.text("Your IP Address", parent.width/2 - 51,parent.height/3 + 5);
    parent.text(((thetablet)parent).getIP(),parent.width/2 - 39,parent.height/3 + 15,400,200);
    configureButtons[3].draw();
  }
  
  public void enterIPView() {
    configureButtons[2].setDisplay(UP);
    parent.text("Please Enter the IP Address of the Session Host:",parent.width/2 - 150,parent.height/3);
    int left = parent.width/2 - longEntryBox.width/2;
    int top = parent.height/3+18;
    parent.image(longEntryBox,left,top);
    parent.text(ipEntry, left+2,top+6,longEntryBox.width-2,longEntryBox.height);
    configureButtons[2].draw();
  }
  
  public void sidebarView() {
    
  }
  
  public void drawingView() {
    PApplet.println("in drawing view");
    menuView = DRAWING;
    menuElements[0].setDisplay(DOWN);
    menuElements[1].setDisplay(UP);
    menuElements[2].setDisplay(UP);
    menuElements[3].setDisplay(UP);
  }
  
  public void textView() {
    parent.println("in text view");
    menuView = TEXT;
    menuElements[0].setDisplay(UP);
    menuElements[1].setDisplay(DOWN);
    menuElements[2].setDisplay(UP);
    menuElements[3].setDisplay(UP);
  }
  
  public void actionsView() {
    parent.println("in actions view");
    menuView = ACTIONS;
    menuElements[0].setDisplay(UP);
    menuElements[1].setDisplay(UP);
    menuElements[2].setDisplay(DOWN);
    menuElements[3].setDisplay(UP);
  }
  
  
  
  
  /** This section manages keypress events **/
  
  public void pressEvent(float x, float y) {
    //parent.println("Button Receiving Press Event: " + x + " , " + y);
    for( int i = 0; i < menuElements.length; i++) {
      Button tmp = menuElements[i];
      if(tmp.withinBounds(x, y)) {
        tmp.press();
      }
    }
    
    if (sessionConfigurationView >= 0) {
      for( int i = 0; i < configureButtons.length; i++) {
        Button tmp = configureButtons[i];
        if(tmp.withinBounds(x, y)) {
          tmp.press();
        }
      }
    }
  }
  
  public void overEvent(float x, float y) {
    for( int i = 0; i < menuElements.length; i++) {
      Button tmp = menuElements[i];
      if(tmp.withinBounds(x, y)) {
        tmp.over();
      }
    }
    
    if (sessionConfigurationView >= 0) {
      for( int i = 0; i < configureButtons.length; i++) {
        Button tmp = configureButtons[i];
        if(tmp.withinBounds(x, y)) {
          tmp.over();
        }
      }
    }
  }
  
  public void releaseEvent(float x, float y) {
    for( int i = 0; i < menuElements.length; i++) {
      Button tmp = menuElements[i];
      if(tmp.withinBounds(x, y)) {
        tmp.release();
      }
    }
    
    if (sessionConfigurationView >= 0) {
      for( int i = 0; i < configureButtons.length; i++) {
        Button tmp = configureButtons[i];
        if(tmp.withinBounds(x, y)) {
          tmp.release();
        }
      }
    }
  }
  
  
  
  
  
  
  

  public void enterIP(String s) {
    ipEntry = ipEntry + s;
  }
  
  public void enterAlias(String s) {
    aliasEntry = aliasEntry + s;
  }
  
  public void backspaceIP() {
    if (ipEntry.length() > 0){
      ipEntry = ipEntry.substring(0, ipEntry.length() - 1);
    }
  }
  
  public void backspaceAlias() {
    if (aliasEntry.length() > 0){
      aliasEntry = aliasEntry.substring(0, aliasEntry.length() - 1);
    }
  }
  
  public String getIPString() {
    return ipEntry;
  }
  
  public String getAliasString() {
    return aliasEntry;
  }
  
  public void setIPString(String str) {
    ipEntry = str;
  }
  
  public void setAliasString(String str) {
    aliasEntry = str;
  }
  
  public void keyEvent(int c) {
    
    int key = c;
    if (selectedTextBox.equals("alias")) {

      if (key != 8) {
        enterAlias("" + key);
      } else {
        backspaceAlias();
      }
      
    } else if (selectedTextBox.equals("ip")) {
      
      if (getIPString().equals("Connection Failed")) {
        setIPString("");
      }
      
      //not sure if this will work...
      if (key != 8) {
        enterIP("" + key);
      } else {
        backspaceIP();
      }
    } 
  }
  
  public void connectionStatus(boolean connected) {
    
    PApplet.println("Inside of connection status: " + connected);
    
    if (connected == true) {
      sessionConfigurationView = HIDDEN;
      drawingView();
    } else {
      ipEntry = "Connection Failed";
    }
    
  }
  
  public int getSessionConfigurationView() {
    return sessionConfigurationView;
  }
  
  public void setConfiguration(Configuration cfg) {
    config = cfg; 
    
    for(int i=0; i <menuElements.length; i++) {
      menuElements[i].setConfig(config);
    }
  }
  
  
  
  
  
  
  private void loadImages() {
  ///load session configuration window images
    configureButtons = new Button[5];
    welcomeBack = parent.loadImage("welcome.png");
    configureBack = parent.loadImage("configureBack.png");
    
    newSessionUp = parent.loadImage("newsession_up.png");
    newSessionDown = parent.loadImage("newsession_down.png");
    configureButtons[0] = new Button(this, config, newSessionUp,newSessionUp,newSessionDown, parent.width / 2 -  newSessionUp.width / 2, parent.height / 3 - newSessionUp.height / 2+10,10,false);
    configureButtons[0].setDisplay(0);
    
    joinSessionUp = parent.loadImage("joinsession_up.png");
    joinSessionDown = parent.loadImage("joinsession_down.png");
    configureButtons[1] = new Button(this, config, joinSessionUp,joinSessionUp,joinSessionDown, parent.width / 2 -  joinSessionUp.width / 2, parent.height / 3 - joinSessionUp.height / 2 + 40,11,false);
    configureButtons[1].setDisplay(0);
    
    joinUp = parent.loadImage("join_up.png");
    joinDown = parent.loadImage("join_down.png");
    configureButtons[2] = new Button(this, config, joinUp,joinUp,joinDown, parent.width / 2 -  joinUp.width / 2, parent.height / 3 - joinUp.height / 2 + 55,12,false);
    
    startUp = parent.loadImage("start_up.png");
    startDown = parent.loadImage("start_down.png");
    configureButtons[3] = new Button(this, config, startUp,startUp,startDown, parent.width / 2 -  startUp.width / 2, parent.height / 3 - startUp.height / 2 + 50,13,false);
    
    longEntryBox = parent.loadImage("ipBox.png");
    entryBox = parent.loadImage("textboxBack.png");
    
    longButton_up  = parent.loadImage("longbutton_up.png");
    longButton_down  = parent.loadImage("longbutton_down.png");
    configureButtons[4] = new Button(this, config, longButton_up,longButton_up,longButton_down, parent.width / 2 -  startUp.width / 2, parent.height / 3 - startUp.height / 2 + 50,14,false,"Enter");
    

    button_up  = parent.loadImage("buttonUp.png");
    button_down  = parent.loadImage("buttonDown.png");
    
    bucket = parent.loadImage("bucket.png");
    vertEdge  = parent.loadImage("vertEdge.png");;
    
  ///load menu images:
    menu = parent.loadImage("menu.png");
    menuElements = new Button[4];
    menuY = parent.height - menu.height + 45;
    
    drawmodeUp = parent.loadImage("drawmode_up.png");
    drawmodeDown = parent.loadImage("drawmode_down.png");
    menuElements[0] = new Button(this, config, drawmodeUp,drawmodeUp,drawmodeDown, 4, parent.height - drawmodeUp.height - 4,00,false);
    
    textmodeUp = parent.loadImage("textmode_up.png");
    textmodeDown = parent.loadImage("textmode_down.png");
    menuElements[1] = new Button(this, config, textmodeUp,textmodeUp,textmodeDown, 8 + textmodeUp.width, parent.height - textmodeUp.height - 4,01,false);
    
    actionsmodeUp = parent.loadImage("actionsmode_up.png");
    actionsmodeDown = parent.loadImage("actionsmode_down.png");
    menuElements[2] = new Button(this, config, actionsmodeUp,actionsmodeUp,actionsmodeDown, 12 + 2 * actionsmodeUp.width, parent.height - actionsmodeUp.height - 4,02,false);
    
    outputUp = parent.loadImage("output_up.png");
    outputDown = parent.loadImage("output_down.png");
    menuElements[3] = new Button(this, config, outputUp,outputDown,outputDown, parent.width - outputUp.width - 4, parent.height - outputUp.height - 4,03,false);
  
    
  }
  

}
